package com.pioneer.gui.invoice.model;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

import java.io.FileInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import java.util.Properties;
import java.util.HashMap;
import java.util.Date;

import javax.swing.event.EventListenerList;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.SwingUtilities;
import javax.swing.text.Document;

import com.pioneer.beans.invoice.InvoiceHeaderModel;
import com.pioneer.beans.invoice.InvoiceDetailModel;

import com.pioneer.gui.invoice.util.Constants;
import com.pioneer.gui.invoice.util.InvoiceDAO;


public class InvoiceModel
extends EventBroadcastModel
implements Constants
{
	public static final int EDIT=0;
	public static final int NEW=1;	
	public static final int CHANGED=0;
	public static final int UNCHANGED=1;
	
	private InvoiceDAO invoiceDAO=new InvoiceDAO();
	// The bean representation of the invoice
    private InvoiceHeaderModel _invoiceHeader; 
    // A representation of the invoice details
    private InvoiceTableModel _invoiceDetails=new InvoiceTableModel();
    // whether to use edit, new
    private int _saveMode;
    // whether the invoice is changed or unchanged
    private int _editStatus;
    private StringBuffer _editStatusMessage=new StringBuffer();
    // represents the current invoice number of this model
    //private String _selectedInvoiceNo;
    
    private DropDownList invoiceId;
    private DropDownList cusId;
    private String name;
    private Document date;
    private DropDownList type;
    private Document entryStatus;  
    private DropDownList sman;
    private float subTotal;
    private float discount;
    private float total;
    private float balance;
    private Document shipVia;
    private String terms;
    DropDownList billToContact;
    Document billAddress;
    Document billCity;
    Document billState;
    Document billZip;
    Document billPhone;
    Document billFax;
    DropDownList shipToContact;
    Document shipAddress;
    Document shipCity;
    Document shipState;
    Document shipZip;
    Document shipPhone;
    Document shipFax;
    
    public InvoiceModel()
    {
    	this.setNew();
	}
	
	/** Use this to initialize the invoice for new entry
	*
	*/
	
	public void setNew()
	{		
		this._saveMode=NEW;
    	this._editStatus=UNCHANGED;
    	// set the default values
    	this.date=null;
    	this.invoiceId=this.invoiceDAO.getNewInvoiceNo();
	    this.cusId=new DropDownList(CUSTOMER_LIST);
    	this.sman=new DropDownList(SALESMAN_LIST);
    	this.type=new DropDownList(INVOICE_TYPE);
	    //this.typeDesc=null;
	    this.entryStatus=null;
	    this.subTotal=0;
	    this.discount=0;
	    this.total=0;
	    this.balance=0;
	    this.shipVia=null;
	    this.terms="";
	    billToContact=new DropDownList();
	    shipToContact=new DropDownList();
	    //this.shipInfo=new String[6];
	    //this.billInfo=new String[6];
	    //this.getInvoiceDetails().setTableData(new Vector(),this.invoiceId);
		this.fireChange();
	}
	
	// The following are setters and getters for this model
    
    public DropDownList getInvoiceId()
    {
    	return this.invoiceId;
    }
    
    public void setInvoiceId(DropDownList invoiceId)
    {
    	this._editStatus=CHANGED;
    	this.invoiceId=invoiceId;
    }
    
    public DropDownList getCusId()
    {
    	return this.cusId;
    }
    
    /*public void setCusId(int cusId)
    {    	
    	this.cusId=cusId;
    }*/
    
    public String getName()
    {
    	return this.name;
    }
    
    public void setName(String name)
    {
    	this._editStatus=CHANGED;
    	this._editStatusMessage.append("\nCustomer");
    	this.name=name;
    }
    
    public Document getDate()
    {
    	return this.date;
    }
    
    public DropDownList getInvoiceType()
    {
    	return this.type;
    }    
    
    /*public void setTypeDesc(String typeDesc)
    {
    	//this.typeDesc=typeDesc;
    	this._editStatus=CHANGED;
    	this._editStatusMessage.append("\nInvoice Type");
    }*/
    
    public Document getEntryStatus()
    {
    	return this.entryStatus;
    }
    
    public DropDownList getSman()
    {
    	return this.sman;
    }
//new DropDownList(SALESMAN_LIST)    
    
    public float getSubTotal()
    {
    	return this.subTotal;
    }
    
    public float getDiscount()
    {
    	return this.discount;
    }
    
    public float getTotal()
    {
    	return this.total;
    }
    
    public float getBalance()
    {
    	return this.balance;
    }
    
    public Document getShipVia()
    {
    	return this.shipVia;
    }
    
    public String getTerms()
    {
    	return this.terms;
    }
    
   /* public void setShipInfo(String [] shipInfo)
    {
    	this._editStatus=CHANGED;
    	this._editStatusMessage.append("\nShipping Information");
    	this.shipInfo=shipInfo;
    }
    
    public String[] getShipInfo()
    {
    	return this.shipInfo;
    }
    
    public void setBillInfo(String[] billInfo)
    {
    	this._editStatus=CHANGED;
    	this._editStatusMessage.append("\nBilling Information");
    	this.billInfo=billInfo;    	
    }
    
    public String[] getBillInfo()
    {
    	return this.billInfo;    	
    }
    */
    
    public DropDownList getBillToContact()
    {
    	return this.billToContact;	
    }
    
    public Document getBillAddress()
    {
    	return this.billAddress;
    }    
    
    public Document getBillCity()
    {
    	return this.billCity;
    }
    
    public Document getBillState()
    {
    	return this.billState;
    }
    
    public Document getBillZip()
    {
    	return this.billZip;
    }
    
    public Document getBillPhone()
    {
    	return this.billPhone;
    }
    
    public Document getBillFax()
    {
    	return this.billFax;
    }

    public DropDownList getShipToContact()
    {
    	return this.shipToContact;	
    }
    
    public Document getShipAddress()
    {
    	return this.shipAddress;
    }    
    
    public Document getShipCity()
    {
    	return this.shipCity;
    }
    
    public Document getShipState()
    {
    	return this.shipState;
    }
    
    public Document getShipZip()
    {
    	return this.shipZip;
    }
    
    public Document getShipPhone()
    {
    	return this.shipPhone;
    }
    
    public Document getShipFax()
    {
    	return this.shipFax;
    }
    
    /** Save the invoice to the database
    */
    
    public void doSave()
    {
    	if (this._saveMode==this.EDIT)
    	{
    		this.invoiceDAO.doSaveExisting(this);
    	}
    	else if (this._saveMode==this.NEW)
    	{
    		this.invoiceDAO.doSaveNew(this);
    	}    	
    	this._invoiceDetails.doSave();
    	this._editStatus=this.UNCHANGED;
    }
    
    /** Rollback the values in the case of a cancel
    * Copy all values from the bean to this model
    */
    
    public void doRollback()
    {
    	this.loadInvoice();
    	// rollback
    }
    
    /** Retrieve the invoice from the database
    */
    
    public void loadInvoice()
    {
    	//this._selectedInvoiceNo=invoice_no;
    	this._saveMode=EDIT;
    	this.refresh();
    }
    
    /** Called by any object that needs to sync up the 
	* invoice header with a new value
	*/
    
	public void setInvoiceHeader(InvoiceHeaderModel header)
	{
		this._invoiceHeader=header;
	}
	
	/** Called by any objects that needs access to
	* the invoice details
	*/	
	
	public InvoiceTableModel getInvoiceDetails()
	{
		return this._invoiceDetails;
	}
	
	/** Called by any object that needs to sync up the 
	* invoice details with a new value
	*/
	
	public void setInvoiceDetails(InvoiceTableModel details)
	{
		this._invoiceDetails=details;
	}
	
	/** Called by any adapters that need to set the save
    * mode based on whether the invoice is a new invoice
    * or an old invoice
    */
    
    public void setSaveMode(int mode)
    {
    	this._saveMode=mode;
    }
    
    /** Called by any adapters
    * to determine if the view
    * needs to be saved
    */

    public int getEditStatus()
    {
    	return this._editStatus;
    }
    
    /** Called by any adapters that
    * need to notify the model 
    * that the view has changed
    */
    
    public void setEditStatus(int editStatus)
    {
    	this._editStatus=editStatus;    	
    }
    
    public String getEditStatusMessage()
    {
    	return this._editStatusMessage.toString();
    }
    
    public void clearEditStatusMessage()
    {
    	this._editStatusMessage=new StringBuffer();
    }
    
    public String getSelectedInvoiceNo()
    {
    	return (String)this.invoiceId.getSelectedItem();
    }
    
    
    /** Invoke the refresher thread 
    */
    
    private void refresh()
    {   
    	Refresher refresher=new Refresher();
    	refresher.start();
    }
    
    /** The refresher which will retrieve
    * from the database without blocking
    */
    
    class Refresher
	extends Thread
	{
    	public void run()
    	{
    		System.out.println("About to load "+InvoiceModel.this.invoiceId.getSelectedItem());
    		// Sync up from the database to the bean (EJB?)    		
    	/*	invoiceDAO.refresh(InvoiceModel.this,_selectedInvoiceNo);    		
    		// Sync up from the database bean
    		//InvoiceModel.this.invoiceId=InvoiceModel.this._invoiceHeader.getInvoiceId();
    		InvoiceModel.this.cusId=InvoiceModel.this._invoiceHeader.getCusId();
    		InvoiceModel.this.name=InvoiceModel.this._invoiceHeader.getName();
    		InvoiceModel.this.date=InvoiceModel.this._invoiceHeader.getDate();
    		InvoiceModel.this.type=InvoiceModel.this._invoiceHeader.getType();
    		InvoiceModel.this.typeDesc=InvoiceModel.this._invoiceHeader.getTypeDesc();
    		InvoiceModel.this.entryStatus=InvoiceModel.this._invoiceHeader.getEntryStatus();
    		InvoiceModel.this.entryStatusDesc=InvoiceModel.this._invoiceHeader.getEntryStatusDesc();
    		//InvoiceModel.this.smanId=InvoiceModel.this._invoiceHeader.getSmanId();
    		//InvoiceModel.this.smanName=InvoiceModel.this._invoiceHeader.getSmanName();
    		InvoiceModel.this.subTotal=InvoiceModel.this._invoiceHeader.getSubTotal();
    		InvoiceModel.this.discount=InvoiceModel.this._invoiceHeader.getDiscount();
    		InvoiceModel.this.total=InvoiceModel.this._invoiceHeader.getTotal();
    		InvoiceModel.this.balance=InvoiceModel.this._invoiceHeader.getBalance();
    		//InvoiceModel.this.shipVia=InvoiceModel.this._invoiceHeader.getShipVia();
    		InvoiceModel.this.terms=InvoiceModel.this._invoiceHeader.getTerms();
    		InvoiceModel.this.shipInfo[0]=InvoiceModel.this._invoiceHeader.getShipAddress();
    		InvoiceModel.this.shipInfo[1]=InvoiceModel.this._invoiceHeader.getShipCity();
    		InvoiceModel.this.shipInfo[2]=InvoiceModel.this._invoiceHeader.getShipState();
    		InvoiceModel.this.shipInfo[3]=InvoiceModel.this._invoiceHeader.getShipZip();
    		InvoiceModel.this.shipInfo[4]=InvoiceModel.this._invoiceHeader.getShipPhone();
    		InvoiceModel.this.shipInfo[5]=InvoiceModel.this._invoiceHeader.getShipFax();    		
    		InvoiceModel.this.billInfo[0]=InvoiceModel.this._invoiceHeader.getBillAddress();
    		InvoiceModel.this.billInfo[1]=InvoiceModel.this._invoiceHeader.getBillCity();
    		InvoiceModel.this.billInfo[2]=InvoiceModel.this._invoiceHeader.getBillState();
    		InvoiceModel.this.billInfo[3]=InvoiceModel.this._invoiceHeader.getBillZip();
    		InvoiceModel.this.billInfo[4]=InvoiceModel.this._invoiceHeader.getBillPhone();
    		InvoiceModel.this.billInfo[5]=InvoiceModel.this._invoiceHeader.getBillFax();    		
        	InvoiceModel.this.fireChange();*/
    	}
    }
}